package com.linran.utils.others;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Enumeration;

public class UriAndUrlLearn {

    /*获取URI属性*/
    /*URI统一资源标识符 可以标识ftp资源，file文件*/
    /*组成:scheme://userInfo@host:port/path?query#fragment
        模式:模式特定部分:片段标识符*/
    /*定界符: / ? & =*/
    /*转义：除定界符，数字，字母，-、_、.、!和~,其他字符都会转义为%加上utf-8编码字符转成16进制字符*/
    @Test
    public void methodLearn() {
        // scheme://userInfo@host:port/path?query#fragment
        URI uri = URI.create("https://userInfo@www.toutiao.com/?is_new_connect=0&is_new_user=%e6%9e%97%e7%84%b6#linlin");
//        URI uri = URI.create("https://www.baidu.com/s?wd=url%20encode&rsv_spt=1&rsv_iqid=0xd5987eb900090c28&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_dl=tb&rsv_enter=1&rsv_sug3=12&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_btype=i&prefixsug=url%2520encode&rsp=6&inputT=1991&rsv_sug4=2836");
        //模式 https
        String scheme = uri.getScheme();
        //url未Decode原始特定部分 //www.toutiao.com/?is_new_connect=0&is_new_user=%e6%9e%97%e7%84%b6
        String rawSchemeSpecificPart = uri.getRawSchemeSpecificPart();
        //url Decode后的原始模式特定部分 //www.toutiao.com/?is_new_connect=0&is_new_user=林然
        String schemeSpecificPart = uri.getSchemeSpecificPart();
        //片段标识符 null
        String fragment = uri.getFragment();
        //授权机构 很多时候Uri都是使用的主机作为授权机构 www.toutiao.com
        String authority = uri.getAuthority();
        //主机 www.toutiao.com
        String host = uri.getHost();
        //端口 -1
        int port = uri.getPort();
        //路径 /
        String path = uri.getPath();
        //请求参数 is_new_connect=0&is_new_user=林然
        String query = uri.getQuery();
        //用户信息
        String userInfo = uri.getUserInfo();

        System.out.printf("scheme:%s%n", scheme);
        System.out.printf("rawSchemeSpecificPart:%s%n", rawSchemeSpecificPart);
        System.out.printf("schemeSpecificPart:%s%n", schemeSpecificPart);
        System.out.printf("fragment:%s%n", fragment);
        System.out.printf("authority:%s%n", authority);
        System.out.printf("host:%s%n", host);
        System.out.printf("port:%s%n", port);
        System.out.printf("path:%s%n", path);
        System.out.printf("query:%s%n", query);
        System.out.printf("userInfo:%s%n", userInfo);
    }

    /*解析相对Uri*/
    @Test
    public void uriPath() {
        URI absolute = URI.create("https://www.baidu.com/path/index.html");
        URI relative = URI.create("/path2/index2.html");// 注意:这里路径部分前面需要加/
        URI resolve = absolute.resolve(relative);
        System.out.printf("resolve:%s%n", resolve); // https://www.baidu.com/path2/index2.html

        URI absoluteURI = URI.create("https://www.baidu.com/path/index.html");
        URI relativeURI = URI.create("https://www.baidu.com");
        URI relativize = relativeURI.relativize(absoluteURI);
        System.out.printf("relativize:%s%n", relativize); // path/index.html
    }

    /*URI比较*/
    @Test
    public void uriEquals() {
        URI uri1 = URI.create("http://localhost:8000/index.html");
        URI uri2 = URI.create("http://LOCALHOST:8000/index.html");
        System.out.println(uri1.equals(uri2)); //不区分大小写
        //输出:true

        //2.
        URI uri3 = URI.create("http://localhost:8000/index/A");
        URI uri4 = URI.create("http://LOCALHOST:8000/index/%41");
        System.out.println(uri3.equals(uri4));
    }

    /*uri string处理*/
    @Test
    public void uriString() {
        URI uri1 = URI.create("http://localhost:8000/index.html?lin=林然");
        System.out.printf("toString:%s%n", uri1.toString()); // http://localhost:8000/index.html?lin=林然
        System.out.printf("toAsciiString:%s%n", uri1.toASCIIString()); // http://localhost:8000/index.html?lin=%E6%9E%97%E7%84%B6 会进行urlEncode
        URI uri = URI.create("http://localhost:8000/index.html?lin=%E6%9E%97%E7%84%B6");
        System.out.printf("decode query:%s%n", uri.getQuery()); // lin=林然
    }


    /**
     * ************************************************************************************************************************
     * protocol://userInfo@host:port/path?query#fragment
     * 协议://用户信息@主机名:端口/路径?查询#片段
     */
    /*构造器方式创建URL*/
    @Test
    public void urlConstructor() throws MalformedURLException {
        URL url = new URL("https", "localhost", 8080, "/path/index.html");
        System.out.println(url.toString());

        URL url2 = new URL("https://127.0.0.1:8080/index");
        System.out.println(url2.toString());

        URL url3 = new URL("https", "127.0.0.1", "/index.html");
        System.out.println(url3.toString());

        URL context = new URL("http", "127.0.0.1", "/index");
        URL url4 = new URL(context, "/login");
        System.out.println(url4);
    }

    /*其他方法获取URL实例*/
    @Test
    public void urlOther() throws IOException {
        URL systemResource = ClassLoader.getSystemResource("name");
        Enumeration<URL> systemREsources = ClassLoader.getSystemResources("name");
        URL resourceOne = UriAndUrlLearn.class.getResource("name");
        URL resourceTwo = UriAndUrlLearn.class.getClassLoader().getResource("name");
        Enumeration<URL> resources = UriAndUrlLearn.class.getClassLoader().getResources("name");
    }

    /*URL的属性*/
    @Test
    public void urlProperty() throws IOException {
        URL url = new URL("https://www.baidu.com");
        InputStream inputStream = url.openStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String buffer = null;
        while ((buffer = bufferedReader.readLine()) != null) {
            System.out.println(buffer);
        }
        inputStream.close();
    }
    /**
     * URLConnection openConnection()
     * openConnection()和openConnection(Proxy proxy)是相似的，只是后者可以使用代理。openConnection()方法为指定的URL新建
     * 一个socket，并且返回一个URLConnection实例，它表示一个网络资源打开的连接，我们可以从这个打开的连接获取一个InputStream实例，
     * 用于读取网络流数据。如果上面的过程出现调用失败，会抛出一个IOException。
     */
}
